package indi.zhifa.recipe.bailan.framework.redis.util;

import indi.zhifa.recipe.bailan.framework.common.util.ZfFileMemo;
import indi.zhifa.recipe.bailan.framework.redis.appproperties.RedisProperty;
import indi.zhifa.recipe.bailan.framework.redis.entity.dto.ScriptFileConfigData;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.hash.Jackson2HashMapper;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@Component
public class RedisScriptUtil {

    private final RedisTemplate<String, Object> mRedisTemplate;
    private final ZfFileMemo mZfFileMemo;
    private final RedisProperty mRedisProperty;

    public RedisScriptUtil(@Qualifier(value = "redisTemplateNoTransaction") RedisTemplate<String, Object> pRedisTemplate,
                           ZfFileMemo pZfFileMemo,
                           RedisProperty pRedisProperty){
        mRedisTemplate = pRedisTemplate;
        mZfFileMemo = pZfFileMemo;
        mRedisProperty = pRedisProperty;
    }

    @PostConstruct
    void init() throws IOException {
        List<ScriptFileConfigData> scriptConfigs = mRedisProperty.getScripts();
        if(CollectionUtils.isEmpty(scriptConfigs)){
            return;
        }
        for(ScriptFileConfigData scriptFileConfigData : scriptConfigs){
            mZfFileMemo.loadFile(scriptFileConfigData.getKey(),scriptFileConfigData.getPath());
        }
    }


    public <T> T execute(String pScriptKey, Class<T> resultType, List<String> pKeys, Object... args){
        String scriptStr = mZfFileMemo.getFileString(pScriptKey);
        DefaultRedisScript<T> defaultRedisScript = new DefaultRedisScript<T>(scriptStr,resultType);

        T rtn = mRedisTemplate.execute(defaultRedisScript, pKeys, args);
        return rtn;
    }
}
